/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appspot.ittrick.drive.trick.cell;

import com.appspot.ittrick.drive.trick.Constants;
import com.appspot.ittrick.drive.trick.DriveTrick;
import com.appspot.ittrick.drive.trick.api.DriveAPIService;
import com.appspot.ittrick.drive.trick.controller.MainController;
import com.appspot.ittrick.drive.trick.model.FileModel;
import com.google.api.services.drive.model.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.HostServices;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.stage.FileChooser;

/**
 *
 * @author takahara
 */
public class FileTableViewTitleCell extends TableCell<FileModel, String> {

    private TextField textField;
    
    private final MenuItem openMenuItem = new MenuItem("ブラウザで開く");
    private final MenuItem duplicateMenuItem = new MenuItem("コピーを作成");
    private final MenuItem changeNameMenuItem = new MenuItem("ファイル名の変更");
    private final Menu sharedMenu = new Menu("共有");
    private final MenuItem sharePublicMenuItem = new MenuItem("公開設定");
    private final MenuItem shareUserMenuItem = new MenuItem("アクセスユーザー管理");
    private final MenuItem deleteFileMenuItem = new MenuItem("削除");
    private final MenuItem downloadMenuItem = new MenuItem("ダウンロード");
    private final MenuItem restorationMenuItem = new MenuItem("元に戻す");
    private final MenuItem changeMineTypeMenuItem = new MenuItem();
    
    /**
     * コンストラクタ
     */
    public FileTableViewTitleCell() {
        sharedMenu.getItems().addAll(sharePublicMenuItem, shareUserMenuItem);
        sharePublicMenuItem.setDisable(true);
        shareUserMenuItem.setDisable(true);
        
        final DriveAPIService driveService = MainController.getInstance().getDriveService();

        // 開くメニューイベント
        openMenuItem.setOnAction(new EventHandler() {
            @Override
            public void handle(Event t) {
                FileModel fileModel = (FileModel) getTableRow().getItem();
                
                HostServices hostServices = DriveTrick.getInstance().getJavaFXHostServices();
                String url = fileModel.getAlternateLink().replace("?usp=drivesdk", "");

                hostServices.showDocument(url);
            }
        });
        
        // 名前変更メニューイベント
        changeNameMenuItem.setOnAction(new EventHandler() {
            @Override
            public void handle(Event t) {
                // treeView を変更可能に設定し、変更開始する
                getTableView().editableProperty().set(true);
                startEdit();
            }
        });

        // 削除メニューイベント
        deleteFileMenuItem.setOnAction(new EventHandler() {
            @Override
            public void handle(Event t) {
                try {

                    FileModel fileModel = (FileModel) getTableRow().getItem();

                    driveService.deleteFile(fileModel.getFile());
                    getTableView().getItems().remove(fileModel);

                } catch (IOException ex) {
                    Logger.getLogger(FolderTreeCell.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        // 元に戻すメニューイベント
        restorationMenuItem.setOnAction(new EventHandler() {
            @Override
            public void handle(Event t) {
                try {
                    FileModel fileModel = (FileModel) getTableRow().getItem();
                    
                    driveService.untrashFile(fileModel.getFile());
                    getTableView().getItems().remove(fileModel);
                } catch (IOException ex) {
                    Logger.getLogger(FileTableViewTitleCell.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        // ダウンロードメニューイベント
        downloadMenuItem.setOnAction(new EventHandler() {
            @Override
            public void handle(Event t) {
                FileModel fileModel = (FileModel) getTableRow().getItem();

                FileChooser fc = new FileChooser();
                fc.setTitle("ダウンロード");
                fc.setInitialFileName(fileModel.getFile().getTitle());
                fc.setInitialDirectory(new java.io.File(System.getProperty("user.home")));

                java.io.File outputFile = fc.showSaveDialog(DriveTrick.getInstance().getStage());

                if (outputFile != null) {
                    MainController.getInstance().fileDownloadTask.run(outputFile, fileModel.getFile());
                }
            }
        });
        
        // 複製メニューイベント
        duplicateMenuItem.setOnAction(new EventHandler() {
            @Override
            public void handle(Event t) {
                try {
                    FileModel fileModel = (FileModel) getTableRow().getItem();
                    
                    File newFile = driveService.makeCopy(fileModel.getFile());
                    getTableView().getItems().add(new FileModel(newFile));
                } catch (IOException ex) {
                    Logger.getLogger(FileTableViewTitleCell.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    @Override
    public void startEdit() {
        try {
            super.startEdit();

            if (textField == null) {
                createTextField();
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        } catch (Exception ex) {
            Logger.getLogger(FileTableViewTitleCell.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void cancelEdit() {
        try {
            super.cancelEdit();

            FileModel fileModel = (FileModel) getTableRow().getItem();

            setText(getItem());
            setGraphic(new ImageView(new Image(fileModel.getIconLink())));

            // treeView を変更不可に設定する
            getTableView().editableProperty().set(false);
        } catch (Exception ex) {
            Logger.getLogger(FileTableViewTitleCell.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void commitEdit(String newValue) {
        try {
            super.commitEdit(newValue);
            
            DriveAPIService driveService = MainController.getInstance().getDriveService();
            FileModel fileModel = (FileModel) this.getTableRow().getItem();
            driveService.updateFile(fileModel.getFile().getId(), fileModel.getFile());
            
            // treeView を変更不可に設定する
            getTableView().editableProperty().set(false);
        } catch (IOException ex) {
            Logger.getLogger(FileTableViewTitleCell.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);

        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            final FileModel fileModel = (FileModel) this.getTableRow().getItem();
            setText(fileModel.getTitle());
            setGraphic(new ImageView(new Image(fileModel.getIconLink())));
            
            setFileContextMenu(fileModel.getFile());
            
            // フォルダを開く
            this.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getClickCount() == 2) {

                        if (fileModel.getFile().getMimeType().equals(Constants.GOOGLE_FILE_TYPES_ENUM.folder.getMineType())) {
                            MainController.getInstance().loadFileListTask.loadFilesByFolderId(fileModel.getFile());
                        }

                    }
                }
            });

        }
    }

    private void createTextField() {
        textField = new TextField(getItem());
        FileModel fileModel = (FileModel) this.getTableRow().getItem();
        
        if(fileModel == null) return;
        
        final File file = fileModel.getFile();
        textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent t) {
                if (t.getCode() == KeyCode.ENTER) {
                    file.setTitle(textField.getText());
                    commitEdit(textField.getText());
                }
            }
        });
    }
    
    
    private void setFileContextMenu(File file) {
        
        ContextMenu contextMenu = new ContextMenu();
        
        ImageView openMenuItemIcon = new ImageView(DriveTrick.class.getResource("images/context_menu/open_web.png").toString());
        openMenuItemIcon.setFitHeight(17);
        openMenuItemIcon.setPreserveRatio(true);
        openMenuItem.setGraphic(openMenuItemIcon);
        
        ImageView downloadMenuItemIcon = new ImageView(DriveTrick.class.getResource("images/context_menu/download.png").toString());
        downloadMenuItemIcon.setFitHeight(17);
        downloadMenuItemIcon.setPreserveRatio(true);
        downloadMenuItem.setGraphic(downloadMenuItemIcon);
        
        ImageView deleteFileMenuItemIcon = new ImageView(DriveTrick.class.getResource("images/context_menu/delete.png").toString());
        deleteFileMenuItemIcon.setFitHeight(17);
        deleteFileMenuItemIcon.setPreserveRatio(true);
        deleteFileMenuItem.setGraphic(deleteFileMenuItemIcon);
        
        ImageView sharedMenuIcon = new ImageView(DriveTrick.class.getResource("images/context_menu/secure.png").toString());
        sharedMenuIcon.setFitHeight(17);
        sharedMenuIcon.setPreserveRatio(true);
        sharedMenu.setGraphic(sharedMenuIcon);
        
        // 削除したファイル
        if (file.getExplicitlyTrashed() != null && file.getExplicitlyTrashed()) {
            contextMenu.getItems().addAll(
                restorationMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
        // フォルダー
        }else if(file.getMimeType().equals(Constants.GOOGLE_FILE_TYPES_ENUM.folder.getMineType())) {
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
        // 形式変換
        }else if(getSuffix(file) != null && 
                Constants.CONVERT_TO_GOOGLE_DOCS_FILE_TYPES.indexOf(getSuffix(file)) >= 0) {
            changeMineTypeMenuItem.setText("Googleドキュメントに変換");
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                duplicateMenuItem,
                changeMineTypeMenuItem,
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
            // 形式変換
        }else if(getSuffix(file) != null && 
                Constants.CONVERT_TO_GOOGLE_SPREADSHEET_FILE_TYPES.indexOf(getSuffix(file)) >= 0) {
            changeMineTypeMenuItem.setText("Googleスプレッドシートに変換");
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                duplicateMenuItem,
                changeMineTypeMenuItem,
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
            // 形式変換
        }else if(getSuffix(file) != null && 
                Constants.CONVERT_TO_GOOGLE_PRESENTATIONS_FILE_TYPES.indexOf(getSuffix(file)) >= 0) {
            changeMineTypeMenuItem.setText("Googleプレゼンテーションに変換");
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                duplicateMenuItem,
                changeMineTypeMenuItem,
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
            // 形式変換
        }else if(getSuffix(file) != null && 
                Constants.CONVERT_TO_GOOGLE_DRAWINGS_FILE_TYPES.indexOf(getSuffix(file)) >= 0) {
            changeMineTypeMenuItem.setText("Google図形に変換");
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                duplicateMenuItem,
                changeMineTypeMenuItem,
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
            // 形式変換
        }else if(getSuffix(file) != null && 
                Constants.CONVERT_TO_GOOGLE_OCR_FILE_TYPES.indexOf(getSuffix(file)) >= 0) {
            changeMineTypeMenuItem.setText("Google OCRに変換");
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                duplicateMenuItem,
                changeMineTypeMenuItem,
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
            
        // 通常ファイル
        }else {
            contextMenu.getItems().addAll(
                openMenuItem,
                new SeparatorMenuItem(),
                changeNameMenuItem, 
                duplicateMenuItem,
                new SeparatorMenuItem(),
                sharedMenu,
                downloadMenuItem, 
                new SeparatorMenuItem(), 
                deleteFileMenuItem);
        }
        
        setContextMenu(contextMenu);
    }
    
    /**
     * ファイル拡張子取得
     * @param fileName
     * @return 
     */
    private static String getSuffix(File file) {
        String fileName = file.getTitle();
        if (fileName == null) {
            return null;
        }
        int point = fileName.lastIndexOf(".");
        if (point != -1) {
            return fileName.substring(point + 1);
        }
        return null;
    }
    
}
